package com.pronosticnews.client.admin.view.listJournees;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.allen_sauer.gwt.dnd.client.DragEndEvent;
import com.allen_sauer.gwt.dnd.client.DragHandler;
import com.allen_sauer.gwt.dnd.client.DragStartEvent;
import com.allen_sauer.gwt.dnd.client.VetoDragException;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.pronosticnews.client.admin.resources.PronosticnewsAdminResources;
import com.pronosticnews.client.util.ClubWidget;
import com.pronosticnews.client.util.dnd.DragClubUtil;
import com.pronosticnews.client.util.dnd.DragUtil;
import com.pronosticnews.client.util.dnd.DraggableFlexTable;
import com.pronosticnews.client.util.dnd.FlexTableRowDragController;
import com.pronosticnews.client.util.dnd.FlexTableRowDropController;
import com.pronosticnews.shared.model.ClubDto;
import com.pronosticnews.shared.model.JourneeDto;
import com.pronosticnews.shared.model.PartieDto;

public class ListJourneeViewImpl extends Composite implements ListJourneesView {

	interface ListJourneeUiBinder extends UiBinder<Widget, ListJourneeViewImpl> {
	}

	@UiField(provided = true)
	AbsolutePanel panel_dnd_clubs;

	@UiField(provided = true)
	DraggableFlexTable table_clubs_saisons;
	
	@UiField
	ScrollPanel scroll_table_clubs_saisons;

	@UiField
	VerticalPanel panel_parties;
	
	@UiField
	ScrollPanel scroll_panel_parties;

	@UiField(provided = true)
	ValueListBox<JourneeDto> lstJournees = new ValueListBox<JourneeDto>(
			new Renderer<JourneeDto>() {

				@Override
				public String render(JourneeDto journees) {
					return "Journée " + journees.getNumeroOrdre().toString();
				}

				@Override
				public void render(JourneeDto object, Appendable appendable)
						throws IOException {
				}
			});

	@UiField
	DialogBox confirmChangeJourneeBox;

	private Presenter presenter;

	private Map<String, ClubDto> mapClubs;

	private Map<String, Widget> mapDraggableClubs;

	private List<UiPartie> uiParties = new ArrayList<ListJourneeViewImpl.UiPartie>();

	JourneeDto journeeEnCours;

	private FlexTableRowDragController tableRowDragController;

	@UiField(provided = true)
	PronosticnewsAdminResources res;

	private FlexTableRowDropController flexTableRowDropControllerClubsSaisons;

	private DragUtil dragClubUtil;

	public ListJourneeViewImpl() {
		mapClubs = new HashMap<String, ClubDto>();
		mapDraggableClubs = new HashMap<String, Widget>();
		res = GWT.create(PronosticnewsAdminResources.class);
		res.cssListJournees().ensureInjected();

		initClubsDragnDrop();

		initWidget(GWT.<ListJourneeUiBinder> create(ListJourneeUiBinder.class)
				.createAndBindUi(this));

	}

	@Override
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}

	private void initClubsDragnDrop() {
		panel_dnd_clubs = new AbsolutePanel();
		dragClubUtil = new DragClubUtil();

		tableRowDragController = new FlexTableRowDragController(panel_dnd_clubs, dragClubUtil);
		tableRowDragController.addDragHandler(new DragHandler() {

			@Override
			public void onPreviewDragStart(DragStartEvent event)
					throws VetoDragException {
			}

			@Override
			public void onPreviewDragEnd(DragEndEvent event)
					throws VetoDragException {
			}

			@Override
			public void onDragStart(DragStartEvent event) {
			}

			@Override
			public void onDragEnd(DragEndEvent event) {
			}
		});

		table_clubs_saisons = new DraggableFlexTable(tableRowDragController);

		flexTableRowDropControllerClubsSaisons = new FlexTableRowDropController(
				table_clubs_saisons,dragClubUtil);
		tableRowDragController
				.registerDropController(flexTableRowDropControllerClubsSaisons);
	}

	@Override
	public void setJournees(List<JourneeDto> result) {
		for (JourneeDto journeeDto : result) {
			lstJournees.setValue(journeeDto);
		}
		lstJournees.setValue(result.get(0));
		journeeEnCours = result.get(0);
		presenter.getParties(lstJournees.getValue());
	}

	@UiHandler({ "lstJournees" })
	void onLstChangeJournee(ValueChangeEvent<JourneeDto> event) {
		confirmChangeJourneeBox.center();
	}

	@UiHandler("btValiderChange")
	void onClickValiderChangeJournee(ClickEvent event) {
		table_clubs_saisons.removeAllRows();
		mapDraggableClubs.clear();
		int row = 0;
		for (ClubDto clubDto : mapClubs.values()) {
			ClubWidget clubWidget = new ClubWidget(clubDto);
			table_clubs_saisons.addDraggableRow(clubWidget,0);
			mapDraggableClubs.put(clubDto.getNom(),
					table_clubs_saisons.getWidget(row, 0));
			row++;
		}

		journeeEnCours = lstJournees.getValue();
		presenter.getParties(lstJournees.getValue());
		confirmChangeJourneeBox.hide();

	}

	@UiHandler("btAnnulerChange")
	void onClickAnnulerChangeJournee(ClickEvent event) {
		lstJournees.setValue(journeeEnCours);
		confirmChangeJourneeBox.hide();
	}

	@UiHandler("btEnregistrer")
	void onClickEnregistrer(ClickEvent event) {
		List<PartieDto> parties = new ArrayList<PartieDto>();
		PartieDto partie = null;
		boolean change = false;
		for (UiPartie uiPartie : uiParties) {
			change = false;
			partie = uiPartie.getPartie();
			if (uiPartie.getClub1().getRowCount() == 1
					&& uiPartie.getClub1().getWidget(0, 0) != null) {
				ClubDto club1 = ((ClubWidget) uiPartie.getClub1().getWidget(0,
						0)).getClub();
				if (club1 != null && club1 != partie.getEquipe1()) {
					partie.setEquipe1(club1);
					change = true;
				}
			}
			if (uiPartie.getClub2().getRowCount() == 1
					&& uiPartie.getClub2().getWidget(0, 0) != null) {
				ClubDto club2 = ((ClubWidget) uiPartie.getClub2().getWidget(0,
						0)).getClub();
				if (club2 != null && club2 != partie.getEquipe2()) {
					partie.setEquipe2(club2);
					change = true;
				}
			}

			if (!"".equals(uiPartie.getScore1().getText())) {
				Integer newScore1 = Integer.parseInt(uiPartie.getScore1()
						.getText());
				if (newScore1 != partie.getScoreEquipe1()) {
					partie.setScoreEquipe1(newScore1);
					change = true;
				}
			}
			if (!"".equals(uiPartie.getScore2().getText())) {
				Integer newScore2 = Integer.parseInt(uiPartie.getScore2()
						.getText());
				if (newScore2 != partie.getScoreEquipe2()) {
					partie.setScoreEquipe2(newScore2);
					change = true;
				}
			}
			if (change) {
				parties.add(partie);
			}
		}
		presenter.updateParties(parties);
	}

	@Override
	public void setClubs(List<ClubDto> result) {
		table_clubs_saisons.removeAllRows();
		mapClubs.clear();
		mapDraggableClubs.clear();
		int row = 0;
		for (ClubDto clubDto : result) {
			mapClubs.put(clubDto.getNom(), clubDto);
			ClubWidget clubWidget = new ClubWidget(clubDto);
			table_clubs_saisons.addDraggableRow(clubWidget,0);
			mapDraggableClubs.put(clubDto.getNom(),
					table_clubs_saisons.getWidget(row, 0));
			row++;
		}
		
		scroll_table_clubs_saisons.setHeight(panel_dnd_clubs.getOffsetHeight()-15+"px");
		table_clubs_saisons.setHeight(panel_dnd_clubs.getOffsetHeight()-15+"px");
	}

	@Override
	public void setParties(List<PartieDto> parties) {
		tableRowDragController.unregisterDropControllers();
		tableRowDragController
				.registerDropController(flexTableRowDropControllerClubsSaisons);
		panel_parties.clear();
		HorizontalPanel panelPartie = null;
		DraggableFlexTable txtClub1 = null;
		DraggableFlexTable txtClub2 = null;
		FlexTableRowDropController flexTableRowDropControllerClub1 = null;
		FlexTableRowDropController flexTableRowDropControllerClub2 = null;
		TextBox txtScore1 = null;
		TextBox txtScore2 = null;
		uiParties.clear();
		for (PartieDto partie : parties) {
			panelPartie = new HorizontalPanel();
			txtClub1 = new DraggableFlexTable(tableRowDragController);
			txtClub2 = new DraggableFlexTable(tableRowDragController);
			txtClub1.setStyleName(res.cssListJournees().txt_clubs_partie());
			txtClub2.setStyleName(res.cssListJournees().txt_clubs_partie());
			flexTableRowDropControllerClub1 = new FlexTableRowDropController(
					txtClub1,dragClubUtil);
			flexTableRowDropControllerClub2 = new FlexTableRowDropController(
					txtClub2,dragClubUtil);
			tableRowDragController
					.registerDropController(flexTableRowDropControllerClub1);
			tableRowDragController
					.registerDropController(flexTableRowDropControllerClub2);
			txtScore1 = new TextBox();
			txtScore2 = new TextBox();
			txtScore1.setStyleName(res.cssListJournees()
					.txt_clubs_parties_score());
			txtScore2.setStyleName(res.cssListJournees()
					.txt_clubs_parties_score());

			if (partie.getEquipe1() != null) {
				table_clubs_saisons.remove(mapDraggableClubs.get(partie
						.getEquipe1().getNom()));
				ClubWidget clubWidget = new ClubWidget(partie.getEquipe1());
				txtClub1.addDraggableRow(clubWidget ,0);
			}
			if (partie.getEquipe2() != null) {
				table_clubs_saisons.remove(mapDraggableClubs.get(partie
						.getEquipe2().getNom()));				
				ClubWidget clubWidget = new ClubWidget(partie.getEquipe2());
				txtClub2.addDraggableRow(clubWidget ,0);
			}
			if (partie.getScoreEquipe1() != null) {
				txtScore1.setText(partie.getScoreEquipe1().toString());
			} else {
				txtScore1.setText("0");
			}
			if (partie.getScoreEquipe2() != null) {
				txtScore2.setText(partie.getScoreEquipe2().toString());
			} else {
				txtScore2.setText("0");
			}

			panelPartie.add(txtClub1);
			panelPartie.add(txtScore1);
			panelPartie.add(txtScore2);
			panelPartie.add(txtClub2);

			UiPartie uiPartie = new UiPartie();
			uiPartie.setPartie(partie);
			uiPartie.setClub1(txtClub1);
			uiPartie.setClub2(txtClub2);
			uiPartie.setScore1(txtScore1);
			uiPartie.setScore2(txtScore2);
			uiParties.add(uiPartie);
			panel_parties.add(panelPartie);
			
			scroll_panel_parties.setHeight(panel_dnd_clubs.getOffsetHeight()-15+"px");
			panel_parties.setHeight(panel_dnd_clubs.getOffsetHeight()-15+"px");
		}
	}

	private class UiPartie {
		PartieDto partie;
		DraggableFlexTable club1;
		DraggableFlexTable club2;
		TextBox score1;
		TextBox score2;

		public PartieDto getPartie() {
			return partie;
		}

		public void setPartie(PartieDto partie) {
			this.partie = partie;
		}

		public DraggableFlexTable getClub1() {
			return club1;
		}

		public void setClub1(DraggableFlexTable club1) {
			this.club1 = club1;
		}

		public DraggableFlexTable getClub2() {
			return club2;
		}

		public void setClub2(DraggableFlexTable club2) {
			this.club2 = club2;
		}

		public TextBox getScore1() {
			return score1;
		}

		public void setScore1(TextBox score1) {
			this.score1 = score1;
		}

		public TextBox getScore2() {
			return score2;
		}

		public void setScore2(TextBox score2) {
			this.score2 = score2;
		}

	}
}
